package com.ys.service.purchase.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ys.entity.storage.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ys.config.MenuId;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.purchase.TcgPurchaseAppointOrder;
import com.ys.entity.purchase.TcgPurchaseAppointOrderItem;
import com.ys.entity.purchase.TcgPurchaseAppointOrderProductComponent;
import com.ys.entity.purchase.TcgPurchaseContract;
import com.ys.entity.purchase.TcgPurchaseContractItem;
import com.ys.entity.purchase.TcgPurchaseInStorage;
import com.ys.entity.purchase.TcgPurchasePreStorageSon;
import com.ys.enume.storage.TccStockSourceEnum;
import com.ys.mapper.purchase.PurchaseMapper;
import com.ys.mapper.purchase.TcgPurchaseAppointOrderProductComponentMapper;
import com.ys.mapper.purchase.TcgPurchaseContractItemMapper;
import com.ys.mapper.purchase.TcgPurchaseInStorageMapper;
import com.ys.mapper.storage.TccAssembleErrorMapper;
import com.ys.mapper.storage.TccAssembleItemMapper;
import com.ys.mapper.storage.TccAssembleMapper;
import com.ys.service.purchase.TcgPurchaseInStorageService;
import com.ys.service.storage.TccStockControlService;
import com.ys.service.sys.CommonApiService;
import com.ys.vo.R;

@Service("tcgPurchaseInStorageService")
public class TcgPurchaseInStorageServiceImpl implements TcgPurchaseInStorageService {

    @Autowired
    private PurchaseMapper purchaseMapper;
    @Autowired
    private TcgPurchaseInStorageMapper tcgPurchaseInStorageMapper;

    @Autowired
    private TccStockControlService tccStockControlService;

    @Autowired
    private TcgPurchaseContractItemMapper tcgPurchaseContractItemMapper;

    @Autowired
    private TcgPurchaseAppointOrderProductComponentMapper tpComponentMapper;

    @Autowired
    private CommonApiService<TccAssemble> commonService;

    @Autowired
    private TccAssembleMapper tccAssembleMapper;

    @Autowired
    private TccAssembleItemMapper tccAssembleItemMapper;

    @Autowired
    private TccAssembleErrorMapper tccAssembleErrorMapper;

    /**
     * 采购入库
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R updateRk(Map<String, Object> params, Long menuId) throws Exception{
        if (params.get("listId") == null){
            return R.error("采购入库数据未选择!");
        }
        if (params.get("chw") == null){
            return R.error("货位数据未选择!");
        }
        String listId = params.get("listId").toString();
        String[] split = (listId.substring(1, listId.length()-1)).split(",");
        for (int i = 0; i < split.length; i++) {
            TcgPurchaseInStorage tcgPurchaseInStorage = new TcgPurchaseInStorage().setId(new Long(split[i])).queryFirst();
            tcgPurchaseInStorage.setChw(params.get("chw").toString());
            tcgPurchaseInStorageMapper.update(tcgPurchaseInStorage);
        }
        return R.ok();
    }

    /**
     * 入库审核
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R updateSh(Map<String, Object> params, Long menuId) throws Exception{
        try {
            if (params.get("listId") == null){
                return R.error("采购入库数据未选择!");
            }
            ThrOperateCompanyApply thrOperateCompanyApply;
            BigDecimal purchaseTotalPriceAll = BigDecimal.ZERO;
            Integer source = 0;
            String remark = "";
            String sourceBid = "";
            String listId = params.get("listId").toString();
            String[] split = (listId.substring(1, listId.length()-1)).split(",");
            for (int i = 0; i < split.length; i++) {
                TcgPurchaseInStorage tcgPurchaseInStorage = new TcgPurchaseInStorage().setId(new Long(split[i])).queryFirst();


                //查询公司信息
                thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(tcgPurchaseInStorage.getVgsbm()).queryFirst();

                source = TccStockSourceEnum.Source.TCG_PurchaseInStorage.value;
                if (tcgPurchaseInStorage.getDocumentSource() == 0){
                    remark = "采购入库新增库存数据";
                    sourceBid = tcgPurchaseInStorage.getBid();
                }else {
                    remark = "组装报错新增库存数据";
                    sourceBid = tcgPurchaseInStorage.getPurchasePreStorageBid();
                }
                purchaseTotalPriceAll = new BigDecimal(tcgPurchaseInStorage.getSubStorageNum()).multiply(tcgPurchaseInStorage.getSubPurchasePrice()).setScale(2, BigDecimal.ROUND_HALF_UP);
                //入子件库存数据
                String companyVid = tcgPurchaseInStorage.getCompanyVid();
                Long sourceId = tcgPurchaseInStorage.getId();
                R add = tccStockControlService.inWithRunning(tcgPurchaseInStorage.getBid(),tcgPurchaseInStorage.getChw(),tcgPurchaseInStorage.getSubName(),
                        tcgPurchaseInStorage.getSubStorageNum(),tcgPurchaseInStorage.getSubCode(),tcgPurchaseInStorage.getSubStorageNum(),tcgPurchaseInStorage.getSubPurchasePrice(),
                        purchaseTotalPriceAll,BigDecimal.ZERO,BigDecimal.ZERO,
                        thrOperateCompanyApply.getVgsbm(),new Date(),0,
                        sourceBid,source,remark, companyVid,sourceBid,sourceId);
                if (add.getCode() == 1){
                    throw new RuntimeException(add.getMsg());
                }
                //添加库存id
                tcgPurchaseInStorage.setStockControlId(Long.valueOf(add.get("data").toString()));


                //回填采购合同的完整性和入库数量(正常途径 预入库动作)
                if (tcgPurchaseInStorage.getDocumentSource() == 0){
                    //预约采购入库子件
                    TcgPurchasePreStorageSon tcgPurchasePreStorageSon = new TcgPurchasePreStorageSon().setId(Long.valueOf(tcgPurchaseInStorage.getPurchasePreStorageSonId())).queryFirst();

                    //采购合同子件
                    TcgPurchaseContractItem tcgPurchaseContractItem = new TcgPurchaseContractItem().setId(tcgPurchasePreStorageSon.getPurchaseContractItemId()).queryFirst();

                    //预约采购单
                    TcgPurchaseAppointOrderProductComponent tcgPurchaseAppointOrderProductComponent = new TcgPurchaseAppointOrderProductComponent().setId(tcgPurchaseContractItem.getOrderProductComponentId()).queryFirst();

                    //判断采购合同子件是否完整入库
                    tcgPurchaseContractItem.setSubWarehousingNum(tcgPurchaseContractItem.getSubWarehousingNum() + tcgPurchaseInStorage.getSubStorageNum());
                    if (tcgPurchaseContractItem.getSubPurchaseNum().equals(tcgPurchaseContractItem.getSubWarehousingNum())){
                        tcgPurchaseContractItem.setSubWarehousingState(1);//1完整
                    }
                    tcgPurchaseContractItemMapper.update(tcgPurchaseContractItem);

                    //判断预约采购单子件是否完整入库
                    tcgPurchaseAppointOrderProductComponent.setSubStorageNumber(tcgPurchaseAppointOrderProductComponent.getSubStorageNumber() + tcgPurchaseInStorage.getSubStorageNum());
                    if (tcgPurchaseAppointOrderProductComponent.getSubPurchaseNumber().equals(tcgPurchaseAppointOrderProductComponent.getSubStorageNumber())){
                        tcgPurchaseAppointOrderProductComponent.setStatePurchaseStorage(1);//1完整
                    }
                    tpComponentMapper.update(tcgPurchaseAppointOrderProductComponent);

                    //判断是否预约采购主表全部采购生成商品组装单
                    TcgPurchaseAppointOrderItem tcgPurchaseAppointOrderItem = new TcgPurchaseAppointOrderItem().setId(tcgPurchaseAppointOrderProductComponent.getPid()).queryFirst();
                    Integer count = new TcgPurchaseAppointOrderProductComponent().setPid(tcgPurchaseAppointOrderItem.getId()).setStatePurchaseStorage(0).count();
                    if (count == 0) {
                        //查询预约采购单
                        TcgPurchaseAppointOrder tcgPurchaseAppointOrder = new TcgPurchaseAppointOrder().setBid(tcgPurchaseAppointOrderItem.getPbid()).queryFirst();
                        //新增商品组装
                        R r = addTccAssemble(tcgPurchaseAppointOrder,tcgPurchaseAppointOrderItem,tcgPurchaseInStorage,tcgPurchaseContractItem);
                        if (r.getCode() == 1) {
                            throw new RuntimeException(r.getMsg());
                        }
                        tcgPurchaseInStorage.setAssembledStatus(1);
                    }
                }else {
                    //采购报错单
                    TccAssembleError tccAssembleError = new TccAssembleError().setBid(tcgPurchaseInStorage.getPurchasePreStorageBid()).queryFirst();
                    tccAssembleError.setInStorageStatus(1);//实际入库
                    tccAssembleErrorMapper.update(tccAssembleError);
                    //商品组装子件
                    TccAssembleItem tccAssembleItem = new TccAssembleItem().setId(tccAssembleError.getAssembleItemId()).queryFirst();
                    //商品组装单
                    TccAssemble tccAssemble = new TccAssemble().setBid(tccAssembleItem.getPbid()).queryFirst();

                    //这个组装单下所有的子件是否产生入库
                    Integer count = new TccAssembleItem()
                            .addLeftJoin("TCC_AssembleError tae ON tae.AssembleItemId = A.id")
                            .where(" tae.InStorageStatus = 0 AND A.pBid = '" + tccAssembleItem.getPbid() + "'").count();
                    if (count == 0) {
                        //查询预约采购商品表
                        TcgPurchaseAppointOrderItem tcgPurchaseAppointOrderItem = new TcgPurchaseAppointOrderItem().setId(tccAssemble.getAppointOrderItemId()).queryFirst();
                        //查询月月采购主表
                        TcgPurchaseAppointOrder tcgPurchaseAppointOrder = new TcgPurchaseAppointOrder().setBid(tcgPurchaseAppointOrderItem.getPbid()).queryFirst();

                        //新增商品组装
                        R r = addTccAssembleYc(tcgPurchaseAppointOrder,tcgPurchaseAppointOrderItem,tcgPurchaseInStorage,tccAssembleError,tccAssemble);
                        if (r.getCode() == 1) {
                            throw new RuntimeException(r.getMsg());
                        }
                    }
                    tcgPurchaseInStorage.setAssembledStatus(1);
                }
                //入库状态变更为已入库
                tcgPurchaseInStorage.setStorageStatus(1);
                tcgPurchaseInStorageMapper.update(tcgPurchaseInStorage);

            }
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }

        return R.ok();
    }

    /**
     * 新增组装数据
     * @param tcgPurchaseAppointOrder 预约采购单
     * @param tcgPurchaseAppointOrderItem 预约采购单商品
     * @param tcgPurchaseInStorage 采购入库
     * @return
     */
    private R addTccAssemble(TcgPurchaseAppointOrder tcgPurchaseAppointOrder,TcgPurchaseAppointOrderItem tcgPurchaseAppointOrderItem,
                             TcgPurchaseInStorage tcgPurchaseInStorage,TcgPurchaseContractItem tcgPurchaseContractItem ){
        try {
            Integer subPlanStorageNum = 0;
            Long stockControlId = 0L;
            //母件组装数量(预计) = 采购的母件数量
            Integer parentPreAssembleNumber = tcgPurchaseAppointOrderItem.getReserveNumber();
            BigDecimal parentSinglePrice = new BigDecimal(tcgPurchaseContractItem.getSubBomNumber()).multiply(tcgPurchaseContractItem.getSubPurchasePrice());
            String bid = commonService.getCommonNextBid(MenuId.TCC_Assemble);
            int sourceType = 1;
            Long assembleErrorId = null;
            TccAssemble tccAssemble = TccAssemble.tccAssemble(bid,0,null,sourceType,tcgPurchaseAppointOrder.getId(),tcgPurchaseAppointOrderItem.getId(),
                    parentPreAssembleNumber,0, parentSinglePrice,assembleErrorId,tcgPurchaseInStorage.getCompanyVid(),
                    tcgPurchaseInStorage.getVgsbm(),1);
            tccAssembleMapper.insert(tccAssemble);

            //新增组装子件数据
            List<TcgPurchaseAppointOrderProductComponent> componentList = new TcgPurchaseAppointOrderProductComponent().setPid(tcgPurchaseAppointOrderItem.getId()).queryList();
            for (TcgPurchaseAppointOrderProductComponent  tcgPurchaseAppointOrderProductComponent : componentList){
                //查询采购合同id
                TcgPurchaseContract tcgPurchaseContract = new TcgPurchaseContract().setBid(tcgPurchaseInStorage.getPurchaseContractBid()).queryFirst();
                //查询对应入库数据
                List<TcgPurchaseInStorage> tcgPurchaseInStorageList = new TcgPurchaseInStorage().setPurchaseAppointOrderProductComponentId(
                		tcgPurchaseAppointOrderProductComponent.getId()).queryList();
                for (TcgPurchaseInStorage tcgPurchaseInStorage1 : tcgPurchaseInStorageList){
                    //实际采购数量
                    subPlanStorageNum = tcgPurchaseInStorage1.getSubStorageNum();
                    stockControlId = tcgPurchaseInStorage1.getStockControlId();
                    if (tcgPurchaseInStorage.getId().equals(tcgPurchaseInStorage1.getId())){
                        tcgPurchaseInStorage1.setAssembledStatus(1);
                        tcgPurchaseInStorageMapper.update(tcgPurchaseInStorage1);

                        stockControlId = tcgPurchaseInStorage.getStockControlId();
                    }
                    TccAssembleItem tccAssembleItem = TccAssembleItem.tccAssembleItem(tccAssemble.getBid(),tcgPurchaseAppointOrderProductComponent.getId(),
                            tcgPurchaseContract.getId(),stockControlId,tcgPurchaseInStorage1.getId(),subPlanStorageNum,subPlanStorageNum,0,1);
                    tccAssembleItemMapper.insert(tccAssembleItem);

                    if (tcgPurchaseInStorage.getId() != tcgPurchaseInStorage1.getId()){
                        tcgPurchaseInStorage1.setAssembledStatus(1);
                        tcgPurchaseInStorageMapper.update(tcgPurchaseInStorage1);
                    }
                }
            }
        } catch (Exception e) {
            return R.error("新增组装数据失败!");
        }
        return R.ok();
    }

    /**
     * 新增组装数据(异常组装)
     * @param tcgPurchaseAppointOrder 预约采购单
     * @param tcgPurchaseAppointOrderItem 预约采购单商品
     * @param tcgPurchaseInStorage 采购入库
     * @param tccAssembleError 组装报错
     * @param tccAssembleNew 组装报错来源下的组信息
     * @return
     */
    private R addTccAssembleYc(TcgPurchaseAppointOrder tcgPurchaseAppointOrder,TcgPurchaseAppointOrderItem tcgPurchaseAppointOrderItem,
                             TcgPurchaseInStorage tcgPurchaseInStorage,TccAssembleError tccAssembleError ,TccAssemble tccAssembleNew){
        try {
            Integer subPlanStorageNum = 0;
            //母件组装数量(预计) = 采购的母件数量 - 已经组装过的数量
            Integer parentPreAssembleNumber = tcgPurchaseAppointOrderItem.getReserveNumber() - tccAssembleNew.getParentAssembleNumber();
            BigDecimal parentSinglePrice = tccAssembleNew.getParentSinglePrice();
            String bid = commonService.getCommonNextBid(MenuId.TCC_Assemble);
            int sourceType = 2;
            TccAssemble tccAssemble = TccAssemble.tccAssemble(bid,0,null,sourceType,tcgPurchaseAppointOrder.getId(),tcgPurchaseAppointOrderItem.getId(),
                    parentPreAssembleNumber,0, parentSinglePrice,tccAssembleError.getId(),tcgPurchaseInStorage.getCompanyVid(),
                    tcgPurchaseInStorage.getVgsbm(),1);
            tccAssembleMapper.insert(tccAssemble);

            //获取商品组装数据
            List<TccAssembleItem> tccAssembleItemList = new TccAssembleItem().setPbid(tccAssembleNew.getBid()).queryList();
            for (TccAssembleItem tccAssembleItem : tccAssembleItemList){
                //之前剩余的库存直接进行组装
                if (tccAssembleItem.getSubAssembleLeftNum() != 0){
                    //通过组装详情id获取库存来源的id获取库存id
                    Map<String,Object> entity = new TccStockSource()
                            .addLeftJoin("TCC_StockControlRunning B ON B.id = A.StockControlRunningId")
                            .addField("B.StockControlId stockControlId")
                            .where("A.sourceId = " + tccAssembleItem.getId())
                            .setIsNewInventory(1)
                            .queryFirstMap();
                    Long stockControlId = Long.valueOf(entity.get("stockControlId").toString());
                    TccAssembleItem tccAssembleItemNew = TccAssembleItem.tccAssembleItem(tccAssemble.getBid(),tccAssembleItem.getAppointOrderComponentId(),
                            tccAssembleItem.getConstractId(),stockControlId,tccAssembleItem.getPurchaseStorageId(),tccAssembleItem.getSubAssembleLeftNum(),tccAssembleItem.getSubAssembleLeftNum(),0,1);
                    tccAssembleItemMapper.insert(tccAssembleItemNew);
                }
                //异常报错的数据
                if ((tccAssembleItem.getSubPlanStorageNum() - tccAssembleItem.getSubRealStorageNum()) != 0){
                    //子件计划入库数量 - 子件实际入库数量
                    subPlanStorageNum = tccAssembleItem.getSubPlanStorageNum() - tccAssembleItem.getSubRealStorageNum();
                    Long stockControlId = 0L;
                    if (tccAssembleError.getAssembleItemId().equals(tccAssembleItem.getId())){
                        stockControlId = tcgPurchaseInStorage.getStockControlId();
                    }else {
                        //通过组转详情id获取报错单单号获取入库的库存id
                        Map<String, Object> entity = new TcgPurchaseInStorage()
                                .addLeftJoin("TCC_AssembleError B ON B.Bid = A.purchasePreStorageBid")
                                .addLeftJoin("TCC_AssembleItem C ON C.id = B.AssembleItemId")
                                .addField("A.StockControlId stockControlId")
                                .where("C.id = " + tccAssembleItem.getId())
                                .queryFirstMap();
                         stockControlId = Long.valueOf(entity.get("stockControlId").toString());
                    }
                    TccAssembleItem tccAssembleItemNew = TccAssembleItem.tccAssembleItem(tccAssemble.getBid(),tccAssembleItem.getAppointOrderComponentId(),
                            tccAssembleItem.getConstractId(),stockControlId,tcgPurchaseInStorage.getId(),subPlanStorageNum,subPlanStorageNum,0,1);
                    tccAssembleItemMapper.insert(tccAssembleItemNew);
                }
            }
        } catch (Exception e) {
            return R.error("新增组装数据失败!");
        }
        return R.ok();
    }
}
